package cn.idongjia.task.common.util;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;

public class PojoUtils {
    private static Logger logger = LoggerFactory.getLogger(PojoUtils.class);

    /**
     * 将泛型形参给出的类中设置的属性值转换为Map形式的键值对
     * t一般是pojo类
     *
     * @param params
     * @param t
     */
    public static <T extends Object> void flushParams(Map<String, Object> params,T t) {
        if(params == null || t == null) return;

        Class<?> clazz = t.getClass();
        for(; clazz != Object.class ; clazz = clazz.getSuperclass()) {
            try {
                Field[] fields = clazz.getDeclaredFields() ;

                for (int j = 0; j < fields.length; j++) { // 遍历所有属性
                    String name = fields[j].getName(); // 获取属性的名字
                    Object value;

                    logger.debug("{} method flushParams attribute name:{}",PojoUtils.class, name);

                    Method method = t.getClass().getMethod("get" + name.substring(0, 1).toUpperCase() + name.substring(1));
                    value = method.invoke(t);

                    logger.debug("{} attribute value: {}", PojoUtils.class, value);

                    if(value != null)
                        params.put(name, value);
                }
            } catch (Exception e) {}
        }
    }

    /**
     * 将Map形式的键值对中的值转换为泛型形参给出的类中的属性值
     * t一般代表pojo类
     *
     * @param t
     * @param params
     */
    public static <T extends Object> void flushObject(T t, Map<String, Object> params) {
        if(params == null || t == null)
            return;

        Class<?> clazz = t.getClass() ;
        for(; clazz != Object.class ; clazz = clazz.getSuperclass()) {
            try {
                Field[] fields = clazz.getDeclaredFields() ;

                for(int i = 0 ; i< fields.length;i++){
                    String name = fields[i].getName(); // 获取属性的名字
                    logger.debug("{} method flushObject attribute name: {}", PojoUtils.class, name);
                    Object value = params.get(name);
                    if(value != null && !"".equals(value)){
                        //注意下面这句，不设置true的话，不能修改private类型变量的值
                        fields[i].setAccessible(true);
                        fields[i].set(t, value);
                    }
                }
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }

    public static <T extends Object> String encodeToJson(T t)
    {
        ObjectMapper mapper = new ObjectMapper();
        String ret = null;
        try {
            ret = mapper.writeValueAsString(t);
        }
        catch (IOException e)
        {
        }
        return ret;
    }

    public static <T extends Object> T decodeToObject(String json)
    {
        ObjectMapper mapper = new ObjectMapper();
        T ret = null;
        try {
            ret = mapper.readValue(json, (Class<T>) ret.getClass());
        } catch (IOException e)
        {
        }
        return ret;
    }

    public static <T extends Object> T decodeToObject(Class<T> clazz, String json)
    {
        ObjectMapper mapper = new ObjectMapper();
        T ret = null;
        try {
            ret = mapper.readValue(json, clazz);
        } catch (IOException e)
        {
        }
        return ret;
    }
}
